package com.ifyyf.test.forkjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

/**
 * @Author if
 * @Description: What is it
 * @Date 2021-11-07 下午 06:46
 */
public class ForkJoinDemo extends RecursiveTask<Long> {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long start=1L;
        long end=10_0000_0000L;
        ForkJoinDemo forkJoinDemo = new ForkJoinDemo(start,end);
        ForkJoinPool forkJoinPool=new ForkJoinPool();
        //执行任务，没有返回值
//        forkJoinPool.execute(forkJoinDemo);
        //提交任务，获得返回值ForkJoinTask类，然后根据这个类的get获取结果
//        ForkJoinTask<Long> submit = forkJoinPool.submit(forkJoinDemo);
//        System.out.println("submit.get() = " + submit.get());
        //采用invoke唤醒可直接得到返回值，比上一种方法更简便
        Long sum = forkJoinPool.invoke(forkJoinDemo);
        System.out.println("sum = " + sum);

        //使用stream并行流
        Long sum1 = LongStream.rangeClosed(start, end)
                .parallel()
                .reduce(0,Long::sum);
        System.out.println("sum1 = "+sum1);
    }

    private Long start;
    private Long end;
    private Long temp=10000L;

    public ForkJoinDemo(Long start, Long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        //小于临界值时，采取普通循环
        if((end-start)<temp){
            long sum=0L;
            for(long i=start;i<=end;i++){
                sum+=i;
            }
            return sum;
        }
        //超过临界值时，采取fork-join方法
        long mid=(start+end)/2;
        //将其分成两份任务
        ForkJoinDemo fj1=new ForkJoinDemo(start,mid);
        //压入任务队列
        fj1.fork();
        ForkJoinDemo fj2=new ForkJoinDemo(mid+1,end);
        fj2.fork();
        //返回整合的结果
        return fj1.join()+fj2.join();
    }
}
